Dependencies: Pi4j, Raspberry Pi

PlayMusic Class

package tests;
 
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.Pin;
 
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
 
import static com.pi4j.wiringpi.Gpio.delay;
import static com.pi4j.wiringpi.Gpio.delayMicroseconds;
 
public class PlayMusic {
    private final GpioController gpio = GpioFactory.getInstance();
    private final GpioPinDigitalOutput buzzer;
    public static final Map<Character, Integer> TONES = new HashMap<>();
 
    static {
        final char names[] = {'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C', 'D', 'E', 'F', 'G'};
        final int tones[] = {1915, 1700, 1519, 1432, 1275, 1136, 1014, 956, 853, 759, 716, 637, 568};
        for (int i = 0; i < names.length; i++) {
            TONES.put(names[i], tones[i]);
        }
    }
 
    public PlayMusic(Pin p) {
        buzzer = gpio.provisionDigitalOutputPin(p);
    }
 
    public void play(LinkedHashMap<Character, Integer> musicScore) {
        for (Iterator it = musicScore.keySet().iterator(); it.hasNext(); ) {
            Object note = it.next();
            playNote((char) note, musicScore.get(note));
        }
    }
 
    public void play(LinkedHashMap<Character, Integer> musicScore, int tempo) {
        for (Iterator it = musicScore.keySet().iterator(); it.hasNext(); ) {
            Object note = it.next();
            playNote((char) note, musicScore.get(note) * tempo);
        }
    }
 
    public void play(char[] notes, int[] durations) {
        if (notes.length != durations.length)
            throw new IllegalArgumentException("Inconsistent length!");
        else {
            for (int i = 0; i < notes.length; i++) {
                playNote(notes[i], durations[i]);
            }
        }
    }
 
    public void play(String notes, int[] durations) {
        if (notes.length() != durations.length)
            throw new IllegalArgumentException("Inconsistent length!");
        else {
            for (int i = 0; i < notes.length(); i++) {
                playNote(notes.charAt(i), durations[i]);
            }
        }
    }
 
    public void play(String notes, int[] beats, int tempo) {
        if (notes.length() != beats.length)
            throw new IllegalArgumentException("Inconsistent length!");
        else {
            for (int i = 0; i < notes.length(); i++) {
                playNote(notes.charAt(i), beats[i] * tempo);
            }
        }
    }
 
    public void play(char[] notes, int[] beats, int tempo) {
        if (notes.length != beats.length)
            throw new IllegalArgumentException("Inconsistent length!");
        else {
            for (int i = 0; i < notes.length; i++) {
                playNote(notes[i], beats[i] * tempo);
            }
        }
    }
 
    public void playTone(int tone, int duration) {
        for (long i = 0; i < duration * 1000L; i += tone * 2) {
            buzzer.high();
            delayMicroseconds(tone);
            buzzer.low();
            delayMicroseconds(tone);
        }
    }
 
    public void playNote(char note, int duration) {
        if (note == ' ')
            delay(duration);
        else
            playTone(TONES.get(note), duration * 4 / 5);
        delay(duration / 5);
    }
}
 

Class HappyBirthday

package tests;
 
import com.pi4j.io.gpio.*;
 
public class HappyBirthday {
    public static final String notes = "ggagCbggagDCggGECbaffECDC";
    public static final int beats[] = {1, 1, 2, 2, 2, 4, 1, 1, 2, 2, 2, 4, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 4};
    private int tempo = 300;
    private final PlayMusic p;
 
    public HappyBirthday(Pin p, int tempo) {
        this.p = new PlayMusic(p);
        this.tempo = tempo;
    }
 
    public HappyBirthday(Pin p) {
        this.p = new PlayMusic(p);
    }
 
    public void setTempo(int tempo) {
        this.tempo = tempo;
    }
 
    public int getTempo() {
        return tempo;
    }
 
    public void play() {
        p.play(notes, beats, tempo);
    }
}